package com.shijunhao.graduation.service.business.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.shijunhao.graduation.domain.entity.*;
import com.shijunhao.graduation.domain.vo.GoodBadVo;
import com.shijunhao.graduation.enums.DictCode;
import com.shijunhao.graduation.enums.TableName;
import com.shijunhao.graduation.mapper.BusinessUserGoodMapper;
import com.shijunhao.graduation.service.business.IBusinessForumDiscussService;
import com.shijunhao.graduation.service.business.IBusinessNoteDiscussService;
import com.shijunhao.graduation.service.business.IBusinessUserGoodService;
import com.shijunhao.graduation.service.business.IBusinessUserInfoService;
import com.shijunhao.graduation.service.scheduled.HotInfoScheduledService;
import com.shijunhao.graduation.service.system.ISystemDictService;
import com.shijunhao.graduation.service.system.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author shijunhao
 * @since 2022-04-24
 */
@Service
public class BusinessUserGoodServiceImpl extends BaseServiceImpl<BusinessUserGoodMapper, BusinessUserGood> implements IBusinessUserGoodService {


    @Resource
    private HotInfoScheduledService hotInfoScheduledService;

    @Resource
    private ISystemDictService systemDictService;

    @Resource
    private IBusinessNoteDiscussService noteDiscussService;

    @Resource
    private IBusinessForumDiscussService forumDiscussService;
    
    @Resource
    private IBusinessUserInfoService businessUserInfoService;

    @Override
    public BusinessUserGood getOne(Long nid, Integer tableValue, Boolean isGood) {
        return getOneHidden(nid, tableValue, isGood, null);
    }

    @Override
    public BusinessUserGood getOneHidden(Long nid, Integer tableValue, Boolean isGood, Boolean isHidden) {
        OrgUser user = businessUserInfoService.getCurrentUser();
        LambdaQueryWrapper<BusinessUserGood> wrapper = Wrappers.lambdaQuery(BusinessUserGood.class)
                .eq(BusinessUserGood::getNid, nid)
                .eq(BusinessUserGood::getTableName, tableValue)
                .eq(BaseEntity::getCreateBy, user.getId())
                .eq(BusinessUserGood::isGood, isGood);
        if (isHidden != null) {
            wrapper.eq(BusinessUserGood::isHidden, isHidden);
        }
        return getOne(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean doAction(Long nid, Integer tableValue, boolean isGood) {
        int finalAction = doBasicAction(nid,tableValue,isGood);;
        if (isGood) {
            hotInfoScheduledService.updateHotInfo((hotInfo1 -> hotInfo1.setGoods(hotInfo1.getGoods() + finalAction)), tableValue, nid);
        } else {
            hotInfoScheduledService.updateHotInfo((hotInfo1 -> hotInfo1.setBads(hotInfo1.getBads() + finalAction)), tableValue, nid);
        }
        return finalAction == 1;
    }

    @Override
    public GoodBadVo getGoodBadInfo(Integer tableValue, Long nid) {
        GoodBadVo result = new GoodBadVo();
        result.setId(nid);
        Long id = businessUserInfoService.getCurrentUser().getId();
        List<BusinessUserGood> goods = selectByCondition(Wrappers.lambdaQuery(BusinessUserGood.class)
                .eq(BusinessUserGood::getTableName, tableValue)
                .eq(BusinessUserGood::getNid, nid)
                .eq(BusinessUserGood::isHidden, false)
                .eq(BaseEntity::getCreateBy, id));
        for (BusinessUserGood good : goods) {
            if (good.isGood())
                result.setGood(true);
            else
                result.setBad(true);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean discussAction(Long nid, Integer tableValue) {
       int action = doBasicAction(nid,tableValue,true);
        SystemDictItem item = systemDictService.loadByCodeValue(DictCode.TABLE.getCode(), tableValue);
        if(TableName.BUSINESS_NOTE_DISCUSS.getLabel().equals(item.getDictLabel())){
            BusinessNoteDiscuss entity = noteDiscussService.getById(nid);
            entity.setGoods(entity.getGoods()+action);
            noteDiscussService.updateById(entity);
        }else{
            BusinessForumDiscuss entity = forumDiscussService.getById(nid);
            entity.setGoods(entity.getGoods()+action);
            forumDiscussService.updateById(entity);
        }
        return action == 1;
    }

    /**
     * @param nid: 对应表主键id
     * @param tableValue: 表值
     * @param isGood: 是否为点赞
     * @return: 1 点赞或点踩 -1 取消操作
     * @author: shijunhao
     * @date: 2022/4/25 18:02
     * @description: 将对应表的点赞或点踩操作进行
     * 如果没有就是点赞或点踩新增操作
     * 如果有则判断是否被hidden
     *      被hidden表示取消了点赞或点踩
     *      只需要重新更新为不被hidden即可
     */
    private Integer doBasicAction(Long nid, Integer tableValue,boolean isGood){
        BusinessUserGood one = getOne(nid, tableValue, true);
        int action = 0;
        //如果不存在则直接添加，表示新增点赞信息
        if (one == null) {
            BusinessUserGood userGood = new BusinessUserGood();
            userGood.setNid(nid);
            userGood.setTableName(tableValue);
            userGood.setGood(isGood);
            userGood.setHidden(false);
            insertOne(userGood);
            action = 1;
            //如果存在则判断是先存在需要取消还是先被删除需要重现
        } else {
            //先被删除需要重现
            if (one.isHidden()) {
                one.setHidden(false);
                updateById(one);
                action = 1;
                //先不是删除直接取消点赞
            } else {
                one.setHidden(true);
                updateById(one);
                action = -1;
            }
        }
        return action;
    }
}
